package com.udf.service;

import com.udf.bean.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * Created by 张未然 on 2015/9/2.
 */
public class CheckJob {

    private static Logger log = LoggerFactory.getLogger(CheckJob.class);

    //根据url地址，记录首次成功的时间
    private HashMap<String,SuccessRecordingBean> successMap;

    //根据URL地址，记录失败的次数
    private HashMap<String,Integer> failureTimesMap;

    public CheckJob() {
        this.successMap = new HashMap<>();
        failureTimesMap = new HashMap<>();
    }

    @Autowired
    private IBeanReadService readService;

    @Autowired
    private IURLConnectionService connectionService;

    @Autowired
    private IContentMatchService contentMatchService;

    @Autowired
    private IDBNotifyService notifyService;

    public void checkURL(){
        CheckRoot root = readService.getCheckBean();
        if(root!=null){
            List<CheckBean> checkBeanList =  root.getCheckBeanList();
            if(checkBeanList!=null&&!checkBeanList.isEmpty()){
                for (CheckBean checkBean : checkBeanList) {
                    String url = checkBean.getTarget();
                    ReqResultBean result = connectionService.doGet(url,null);
                    if(result.isSuccess()){
                        MatchResultBean match = contentMatchService.match(result.getContent(),checkBean.getKeywords());
                        if(match.isSuccess()){
                            //记录成功的时间
                            recordFirstSuccessTime(checkBean,new Date());
                            log.info("检测-{}-未发现异常",checkBean.getTarget());
                        }else{
                            List<String> unHitKeyWords = match.getUnHitKeyWords();
                            if(unHitKeyWords!=null&&!unHitKeyWords.isEmpty()){
                                for (String unHitKeyWord : unHitKeyWords) {
                                    log.info("检测-{}-发现关键字-{}-被篡改！",checkBean.getTarget(),unHitKeyWord);
                                }
                                notifyFailure(checkBean, result.getCode(), "关键字被篡改",unHitKeyWords);
                            }
                        }
                    }else{
                        log.info("检测-{}-失败，错误代码:{}，状态描述:{}", checkBean.getTarget(), result.getCode(), result.getContent());
                        notifyFailure(checkBean,result.getCode(),result.getContent(),null);

                    }
                }
            }
        }
    }

    public void notifySuccess(){
        notifyService.notifySuccess(successMap);
    }

    private void notifyFailure(CheckBean checkBean, int statusCode,String statusMessage, List<String> unHitKeyWords){
        recordFailureTimes(checkBean);
        clearFirstSuccessTime(checkBean);
        int failureTimes = getFailureTimes(checkBean);
        if(failureTimes>0&&failureTimes<3){
            //记录次数未达两次 写数据库 通知用户
            notifyService.notifyFailure(checkBean.getTarget(),statusCode,statusMessage,unHitKeyWords,new Date());
        }
    }

    private void recordFirstSuccessTime(CheckBean bean,Date checkDate){
        SuccessRecordingBean sucessBean = successMap.get(bean.getTarget());
        if(sucessBean==null){
            sucessBean = new SuccessRecordingBean();
            sucessBean.setSuccessFrom(checkDate);
            sucessBean.setSuccessEnd(checkDate);
            successMap.put(bean.getTarget(), sucessBean);
        }else{
            sucessBean.setSuccessEnd(checkDate);
//            successMap.put(bean.getTarget(),sucessBean);
        }
    }

    private void clearFirstSuccessTime(CheckBean bean){
        successMap.put(bean.getTarget(), null);
    }

    private void recordFailureTimes(CheckBean bean){
        Integer failureTimes = failureTimesMap.get(bean.getTarget());
        if(failureTimes==null){
            failureTimesMap.put(bean.getTarget(),1);
        }else{
            failureTimesMap.put(bean.getTarget(),failureTimes+1);
        }
    }

    private int getFailureTimes(CheckBean bean){
        Integer failureTimes = failureTimesMap.get(bean.getTarget());
        if(failureTimes==null){
            return 1;
        }else{
            return failureTimes.intValue();
        }
    }

}
